import io from './index.js'
import paths from '../paths'
import shpConverterText from '../shpconverter-text'
import shapeFile from '../shapefile'
import utils from '../utils'
import shpConverterTopology from '../shpconverter-topology'
/**
 * Parse content of one or more input files and return a dataset
 * @param {*} obj file data, indexed by file type
 *  File data objects have two properties:
 *    content: Buffer, ArrayBuffer, String or Object
 *    filename: String or null
 * @param {*} opts 
 */
function importContent(obj, opts) {
  let dataset = null
  let fileFmt = ''
  let data = null
  opts = opts || {}
  if (obj.json) {
    data = io.importJSON(obj.json, opts)
    fileFmt = data.format
    dataset = data.dataset
    paths.cleanPathsAfterImport(dataset, opts)
  } else if (obj.text) {
    fileFmt = 'dsv'
    data = obj.text
    dataset = shpConverterText.importDelim2(data, opts)
  } else if (obj.shp) {
    fileFmt = 'shapefile'
    data = obj.shp
    dataset = importShapefile(obj, opts)
    paths.cleanPathsAfterImport(dataset, opts)
  } else if (obj.dbf) {
    fileFmt = 'dbf'
    data = obj.dbf
    dataset = importDbf(obj, opts)
  } else if (obj.prj) {
    // added for -proj command source
    fileFmt = 'prj'
    data = obj.prj
    dataset = {layers: [], info: {prj: data.content}}
  }
  if (!dataset) {
    // stop("Missing an expected input type")
    utils.error('Missing an expected input type')
  }
  // Convert to topological format, if needed
  if (dataset.arcs && !opts.no_topology && fileFmt != 'topojson') {
    shpConverterTopology.buildTopology(dataset);
  }
  // Use file basename for layer name, except TopoJSON, which uses object names
  if (fileFmt != 'topojson') {
    dataset.layers.forEach((lyr) => {
      setLayerName(lyr, filenameToLayerName(data.filename || ''))
    })
  }

  // Add input filename and format to the dataset's 'info' object
  // (this is useful when exporting if format or name has not been specified.)
  if (data.filename) {
    dataset.info.input_files = [data.filename]
  }
  dataset.info.input_formats = [fileFmt]
  return dataset
}
// Deprecated (included for compatibility with older tests)
function importFileContent(content, filename, opts) {
  const type = internal.guessInputType(filename, content)
  const input = {}
  input[type] = {filename: filename, content: content}
  return importContent(input, opts)
}
function importShapefile(obj, opts) {
  const shpSrc = obj.shp.content || obj.shp.filename // read from a file if (binary) content is missing
  const shxSrc = obj.shx ? obj.shx.content || obj.shx.filename : null
  const dataset = shapeFile.importShp(shpSrc, shxSrc, opts)
  const lyr = dataset.layers[0]

  if (obj.dbf) {
    const dbf = importDbf(obj, opts)
    utils.extend(dataset.info, dbf.info)
    lyr.data = dbf.layers[0].data
    // if (lyr.shapes && lyr.data.size() != lyr.shapes.length) {
    //   message("Mismatched .dbf and .shp record count -- possible data loss.");
    // }
  }
  if (obj.prj) {
    dataset.info.prj = obj.prj.content
  }
  return dataset
}
function importDbf(input, opts) {
  opts = utils.extend({}, opts)
  if (input.cpg && !opts.encoding) {
    opts.encoding = input.cpg.content
  }
  const table = shapeFile.importDbfTable(input.dbf.content, opts)
  return {
    info: {},
    layers: [{data: table}]
  }
}
function filenameToLayerName(path) {
  let name = 'layer1'
  let obj = utils.parseLocalPath(path)
  if (obj.basename && obj.extension) { // exclude paths like '/dev/stdin'
    name = obj.basename
  }
  return name
}

// initialize layer name using filename
function setLayerName(lyr, path) {
  if (!lyr.name) {
    lyr.name = utils.getFileBase(path)
  }
}

export default {
  importContent,
  importFileContent,
}